package edu.washington.tcss360.burningpenguins.BPGUI;

import java.awt.Container;
import java.util.ArrayList;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;

import edu.washington.tcss360.burningpenguins.data.Role;

/**
 * Container class for the buttons that go into the side bar of the burning penguins GUI.
 * 
 * Version notes: 	1.1 refactored out button specifics to a factory class.
 * 					1.2 refactored out action specifics to abstract action.
 * 					1.3 changed out layout managers.
 * 
 * @author Sean
 * @version 1.3
 * @since 11/19/2013
 */
public class BPSideBar extends Container {

// 	menuItems, have action listeners in this package.	

	/**
	 * Enables serializing of this object.
	 */
	private static final long serialVersionUID = -917180535751957791L;
	
	/**
	 * Spacing between buttons.
	 */
	private static final int SPACER = 30;

	/**
	 * Default user role, only ability is to login.
	 */
	private static final int USER_ROLE = 0;
	
	/**
	 * The full list of buttons.
	 */
	private final ArrayList<BPButton> BUTTON_GROUPS;
	
	/**
	 * The current role that is active.
	 */
	private int my_role;
	
	/**
	 * The frame that this sidebar is associated with.
	 */
	private final BPFrame my_frame;
	
	/**
	 * Default constructor, for when no one is logged in.
	 */
	protected BPSideBar(final BPFrame frame) {
		this(USER_ROLE, frame);
	}
	
	/**
	 * Explicit constructor.  Defines user role and populates the sidebar for that role.
	 * 
	 * @param user_role the active role.
	 */
	protected BPSideBar(final int user_role, final BPFrame frame) {
		super();
		this.my_frame = frame;
		this.my_role = user_role;
		this.BUTTON_GROUPS = new ArrayList<>();
		this.populateButtons();
		this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		this.setSize(210, 500);
		this.mapButtons();
		this.add(Box.createVerticalStrut(150));
		this.add(new JLabel("Burning Penguins"));
		this.add(new JLabel("Conference Management"));
		this.setVisible(true);
	}
	
	/**
	 * Creates a generic bucket of buttons for switching roles.
	 */
	private void populateButtons() {
		this.BUTTON_GROUPS.add(new BPButton("Login"));
		this.BUTTON_GROUPS.add(new BPButton("Submit"));
		this.BUTTON_GROUPS.add(new BPButton("Get Review"));
		this.BUTTON_GROUPS.add(new BPButton("Edit Submission"));
		this.BUTTON_GROUPS.add(new BPButton("Assign Paper"));
		this.BUTTON_GROUPS.add(new BPButton("Accept Submission"));
		this.BUTTON_GROUPS.add(new BPButton("Designate SubProgram Chairs"));
		this.BUTTON_GROUPS.add(new BPButton("View Status"));
		this.BUTTON_GROUPS.add(new BPButton("View Assignments"));
		
		for(int i = 0; i < this.BUTTON_GROUPS.size(); i++) {
			// TODO: attach actions here?
			this.BUTTON_GROUPS.get(i).BPactionFactory(i, my_frame);
		}
	}
	
	/**
	 * Maps buttons according to active user role.
	 */
	protected void mapButtons() {
		this.removeAll(); // remove current buttons.
		this.add(Box.createVerticalStrut(BPSideBar.SPACER));
		this.add(this.BUTTON_GROUPS.get(BPActions.LOGIN));
		if(this.my_role == Role.PROGRAM_CHAIR) {
			this.add(Box.createVerticalStrut(BPSideBar.SPACER));
			this.add(this.BUTTON_GROUPS.get(BPActions.VIEW_STATUS));
			this.add(Box.createVerticalStrut(BPSideBar.SPACER));
			this.add(this.BUTTON_GROUPS.get(BPActions.VIEW_ASSIGN));
			this.add(Box.createVerticalStrut(BPSideBar.SPACER));
			this.add(this.BUTTON_GROUPS.get(BPActions.DESIGNATE));
			this.add(Box.createVerticalStrut(BPSideBar.SPACER));
			this.add(this.BUTTON_GROUPS.get(BPActions.ACCEPT));
		}
		if(this.my_role == Role.SUBPROGRAM_CHAIR) {
			this.add(Box.createVerticalStrut(BPSideBar.SPACER));
			this.add(this.BUTTON_GROUPS.get(BPActions.ASSIGN));
			this.add(Box.createVerticalStrut(BPSideBar.SPACER));
			this.add(this.BUTTON_GROUPS.get(BPActions.SUBMIT));
		}
		if(this.my_role == Role.REVIEWER) {
			this.add(Box.createVerticalStrut(BPSideBar.SPACER));
			this.add(this.BUTTON_GROUPS.get(BPActions.SUBMIT));			
		}
		if(this.my_role == Role.AUTHOR) {
			this.add(Box.createVerticalStrut(BPSideBar.SPACER));
			this.add(this.BUTTON_GROUPS.get(BPActions.SUBMIT));
			this.add(Box.createVerticalStrut(BPSideBar.SPACER));
			this.add(this.BUTTON_GROUPS.get(BPActions.EDIT));
			this.add(Box.createVerticalStrut(BPSideBar.SPACER));
			this.add(this.BUTTON_GROUPS.get(BPActions.GET_REVIEW));
		}
	}

	/**
	 * Enables role switching.  Enforces the class invariant that the role must be
	 * in the valid range.  If the role is not wit hin the valid range, then the
	 * current role is assigned to generic user role.
	 * 
	 * @param new_role the role to switch to.
	 */
	protected void switchRole(final int new_role) {
		System.err.printf("in sidebar, role switch to %d\n", new_role);
		if(new_role > Role.PROGRAM_CHAIR || new_role < Role.AUTHOR) this.my_role = USER_ROLE;
		else this.my_role = new_role;
		this.mapButtons();
		this.add(Box.createVerticalStrut(150));
		this.add(new JLabel("Burning Penguins"));
		this.add(new JLabel("Conference Management"));
		this.setVisible(true);
		this.repaint();
	}
	
	/**
	 * @return the current role associated with this button list.
	 * @return
	 */
	protected int checkRole() {
		return this.my_role;
	}
	
}
